package com.enlorenz.common.geo.map.google;

import java.io.File;

import com.enlorenz.common.geo.map.arcgis.ArcgisTileFilePathCreator;
import com.enlorenz.common.geo.map.base.FileWrapper;
import com.enlorenz.common.geo.map.base.ITileFilePathCreator;
import com.enlorenz.common.geo.map.base.MapConfig;
import com.enlorenz.common.geo.map.base.TileWrapper;
import com.enlorenz.common.geo.map.callback.IDownloadResultCallback;
import com.enlorenz.common.geo.map.google.GoogleTileFileParser.GoogleTileFileHook;
import com.enlorenz.util.FileUtil;
import com.enlorenz.util.UrlUtil;


/**
 * 抽象的瓦片处理器
 * @author Karma
 */
public abstract class BaseTileCmdConsole implements ITileCmdConsole{
	//配置
	private MapConfig mapConfig;
	//默认的图片缓存
	private byte [] defaultPicBuff;
	public static final String DEFAULT_PIC_NAME="DefaultTile.png";
	
	public BaseTileCmdConsole(){
		
	}
	/**
	 * 如果读取瓦片失败
	 * @param url
	 * @param googleTileWrapper
	 */
	protected void readTileFailed(String url,String filePath,TileWrapper googleTileWrapper){
		if(null == defaultPicBuff){
			try {
				defaultPicBuff=FileUtil.readFromClass(BaseTileCmdConsole.class, DEFAULT_PIC_NAME);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		try {
			//写入默认图片
			FileUtil.writeFile(filePath, defaultPicBuff);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * 获取请求数据的URL
	 * @param googleTileWrapper
	 * @return
	 */
	protected abstract String getSourceUrl(TileWrapper googleTileWrapper);
	
	/**
	 * 创建数据来源创建器
	 * @return
	 */
	protected ITileFilePathCreator createSrcCreator(){
		//输入用argis的文件系统
		//return new GoogleTileFilePathCreator();
		return new ArcgisTileFilePathCreator();
	}
	/**
	 * 创建目标文件创建器
	 * @return
	 */
	protected ITileFilePathCreator createDstCreator(){
		//输出用argis的文件系统
		return new ArcgisTileFilePathCreator();
	}
	
	/**
	 * 开始解析
	 * @throws Exception
	 */
	public void doParse() throws Exception{
		//Google瓦片算法
		GoogleTileParser gtp=new GoogleTileParser();
		gtp.setMapConfig(mapConfig);
		//Google瓦片文件解析
		GoogleTileFileParser googleTileFileParser=new GoogleTileFileParser(gtp);
		googleTileFileParser.setMapConfig(mapConfig);
		//设置输入目录创建着
		googleTileFileParser.setSrcCreator(createSrcCreator());
		//设置输出目录创建者
		googleTileFileParser.setDstCreator(createDstCreator());
		
		googleTileFileParser.setGoogleTileFileHook(new GoogleTileFileHook(){
			@Override
			public void hook(int index, long total,
					FileWrapper srcFileWp,FileWrapper dstFileWp,TileWrapper googleTileWrapper) {
				long st=System.currentTimeMillis();
				
				File dstfileDir=new File(dstFileWp.getDir());
				File srcFile=new File(srcFileWp.getFullPath());
				
				//display("转化:"+ArcgisNameTransform.google2Arcgis(googleTileWrapper));
				String threadName=Thread.currentThread().getName();
				//不覆盖则检测文件是否存在
				if(!mapConfig.isCover()&&srcFile.exists()){
					doResult(st, threadName, IDownloadResultCallback.RESULT_TYPE_SUCCESS_EXISTS,
							"文件已存在", index, total, googleTileWrapper, null);
					return;
				}
				
				if (!dstfileDir.exists()) {
					dstfileDir.mkdirs();
				}
				//图片请求地址
				String reqUrl = getSourceUrl(googleTileWrapper);
				byte[] buff = null;
				int tryTimes=0;
				while(tryTimes<mapConfig.getPicTryTimes()){
					try {
						buff = UrlUtil.readBytes(reqUrl);
						break;
					} catch (Exception e) {
						e.printStackTrace();
						tryTimes++;
					}
				}
				
				if (null != buff) {
					try {
						//写入文件
						FileUtil.writeFile(dstFileWp.getFullPath(), buff);
						doResult(st, threadName, IDownloadResultCallback.RESULT_TYPE_SUCCESS_DOWNLOAD,
								"地图切片成功", index, total, googleTileWrapper, reqUrl);
					} catch (Exception e) {
						doResult(st, threadName, IDownloadResultCallback.RESULT_TYPE_FAILED_WRITE_FILE,
								"写入地图失败", index, total, googleTileWrapper, reqUrl);
						e.printStackTrace();
					}
				} else {
					doResult(st, threadName, IDownloadResultCallback.RESULT_TYPE_FAILED_DOWNLOAD,
							"地图切片失败", index, total, googleTileWrapper, reqUrl);
					readTileFailed(reqUrl, dstFileWp.getFullPath(),googleTileWrapper);
				}
				
			}
		});
		googleTileFileParser.init();
		googleTileFileParser.doParse();
	}
	
	private void doResult(long st,String threadName,int type,String msg,int index,long total,TileWrapper googleTileWrapper,
			String url){
		long ed=System.currentTimeMillis();
		long costTime=(ed-st);
		mapConfig.downloadResult(threadName,type, 
				msg, index, total, googleTileWrapper, url,costTime);
	}

	public void setMapConfig(MapConfig mapConfig) {
		this.mapConfig = mapConfig;
	}

}
